﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DepartmentController.cs" company="">
//   Copyright (c) 2010/2011 All Right Reserved
// </copyright>
// <summary>
//   Contains DepartmentController class declaration.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace IBupro.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    using IBupro.Classes;
    using IBupro.Controllers.Classes;
    using IBupro.Models;

    using iBuproModel;
    using iBuproModel.Repositories.Interfaces;

    /// <summary>
    /// This controller contains actions related to department.
    /// </summary>
    public class DepartmentController : CustomController
    {
        private readonly IDepartmentRepository departmentRepository;

        public DepartmentController()
        {
            this.departmentRepository = this.repositoryService.DepartmentRepositoryCreateInstance();
        }

        [Authorize]
        public ActionResult Index()
        {
            var userRepository = this.repositoryService.UserRepositoryCreateInstance();
            var user = userRepository.GetUserByUserName(User.Identity.Name);
            IEnumerable<Department> departments = this.departmentRepository.GetDepartmentsForUser(user);

            if (departments.Count() == 0)
            {
                this.FlashMessenger.AddMessage(Translator.Instance["noDepartmentToBeManaged"], MessageType.Notice);
                return RedirectToAction("Index", "Home");
            }

            return View(departments);
        }

        [Authorize(Roles = "Admin")]
        public ActionResult Create()
        {
            return View(new Department());
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult Create(Department department)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    this.FlashMessenger.AddMessage(Translator.Instance["cannoctCreateDepartment"], MessageType.Error);
                    return View(department);
                }
                    
                this.departmentRepository.Add(department);
                this.departmentRepository.SaveChanges();

                this.FlashMessenger.AddMessage(Translator.Instance["departmentCreated"], MessageType.Success);
                return RedirectToAction("Index");
            }
            catch
            {
                throw new Exception("Cannot Add Department");
            }
        }

        [Authorize(Roles = "Admin")]
        public ActionResult Delete(int id)
        {
            try
            {
                var department = this.departmentRepository.GetSingle(d => d.Id == id);
                department.Visible = false;
                this.departmentRepository.Update(department);
                this.departmentRepository.SaveChanges();

                this.FlashMessenger.AddMessage(Translator.Instance["departmentDeleted"], MessageType.Success);
                return RedirectToAction("Index");
            }
            catch
            {
                throw new Exception("Cannot Delete Department");
            }
        }

        [Authorize(Roles = "Admin")]
        public ActionResult Details(int id)
        {
            try
            {
                return this.View(this.departmentRepository.First(d => d.Id == id));
            }
            catch
            {
                throw new Exception("Cannot Find Department");
            }
        }


        [Authorize(Roles = "Admin, Principal")]
        public ActionResult Edit(int id)
        {
            try
            {
                return this.View(this.departmentRepository.First(d => d.Id == id));
            }
            catch
            {
                throw new Exception("Cannot Update Department");
            }
        }


        [Authorize(Roles = "Admin, Principal")]
        [HttpPost]
        public ActionResult Edit(Department department)
        {
            if (!ModelState.IsValid)
            {
                this.FlashMessenger.AddMessage(Translator.Instance["cannotUpdateDepartment"], MessageType.Error);
                return View(department);   
            }
                
            this.departmentRepository.Update(department);
            this.departmentRepository.SaveChanges();

            this.FlashMessenger.AddMessage(Translator.Instance["departmentUpdated"], MessageType.Success);
            return RedirectToAction("Index");
        }

        [Authorize(Roles = "Admin")]
        public ActionResult EditPrincipals(int id)
        {
            var department = this.departmentRepository.GetSingle(d => d.Id == id);
            var model = new DepartmentModel(department);

            return View(model);
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult EditPrincipals(int id, DepartmentModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var oldDepartment = this.departmentRepository.GetSingle(u => u.Id == id);

                    if (model.SelectedPrincipals != null)
                    {
                        this.departmentRepository.UpdatePrincipalList(oldDepartment, model.SelectedPrincipals);
                    }

                    this.departmentRepository.SaveChanges();
                }
                else
                {
                    this.FlashMessenger.AddMessage(Translator.Instance["principalsCannotBeUpdated"], MessageType.Error);
                    return View(model);
                }

                this.FlashMessenger.AddMessage(Translator.Instance["principalsUpdated"], MessageType.Success);
                return RedirectToAction("Index");
            }
            catch
            {
                return View(model);
            }
        }

        [Authorize(Roles = "Admin, Principal")]
        public ActionResult EditAdministrators(int id)
        {
            var userRepository = repositoryService.UserRepositoryCreateInstance();
            var department = this.departmentRepository.GetSingle(d => d.Id == id);

            if (User.IsInRole("Principal") && 
                userRepository.GetUserByUserName(User.Identity.Name).DepartmentPrincipalDepartments.Contains(department) == false)
            {
                this.FlashMessenger.AddMessage("You are not principal of this department. You cannot edit administrators.", MessageType.Error);
                return RedirectToAction("Index");
            }
            
            var model = new DepartmentModel(department);

            return View(model);    
        }

        [Authorize(Roles = "Admin, Principal")]
        [HttpPost]
        public ActionResult EditAdministrators(int id, DepartmentModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var oldDepartment = this.departmentRepository.GetSingle(u => u.Id == id);

                    this.departmentRepository.UpdateAdministratorList(oldDepartment, model.SelectedAdministrators);
                    
                    this.departmentRepository.SaveChanges();
                }
                else
                {
                    this.FlashMessenger.AddMessage("Department administrators cannot be updated.", MessageType.Error);
                    return View(model);
                }

                this.FlashMessenger.AddMessage("Department administrators succesfully updated.", MessageType.Success);
                return RedirectToAction("Index");
            }
            catch
            {
                return View(model);
            }
        }

        [Authorize(Roles = "Admin")]
        public ActionResult MakeInvisible(int id)
        {
            try
            {
                var department = this.departmentRepository.GetSingle(d => d.Id == id);
                department.Visible = false;
                this.departmentRepository.Update(department);
                this.departmentRepository.SaveChanges();

                this.FlashMessenger.AddMessage("Department status changed to invisible.", MessageType.Success);
                return RedirectToAction("Index");

            }
            catch
            {
                throw new Exception("Cannot Update Department");
            }
        }

        [Authorize(Roles = "Admin")]
        public ActionResult MakeVisible(int id)
        {
           try
           {

               var department = this.departmentRepository.GetSingle(d => d.Id == id);
               department.Visible = true;
               this.departmentRepository.Update(department);
               this.departmentRepository.SaveChanges();

               this.FlashMessenger.AddMessage("Department status changed to visible.", MessageType.Success);
               return RedirectToAction("Index");
           }
           catch
           {
               throw new Exception("Cannot Update Department");
           }
        }
    }
}
